home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Games / Abalone 1.4.2 / src / Abalone.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-09-21  |  8.6 KB  |  395 lines  |  [TEXT/MPS ]

  1. #define ABALONE_C
  2. #include "Abalone.h"
  3. #undef ABALONE_C
  4.  
  5.  
  6. #pragma segment Main
  7.    
  8. RgnHandle gCursorRgn;
  9.  
  10. #if (defined (powerc) || defined (__SC__)) && ! defined(__MWERKS__)
  11. QDGlobals    qd;
  12. #endif
  13.  
  14.  
  15. //*************************** segment Initialize ******************************
  16.  
  17.  
  18. #pragma segment Initialize
  19.  
  20. #ifndef THINK_C
  21. extern
  22. #ifdef __cplusplus
  23. "C"
  24. #endif
  25. void _DataInit();
  26. // So we can unload its segment, %A5Init.
  27. #endif
  28.  
  29.  
  30. void
  31. Initialize (void)
  32. {
  33.     Handle menuBar;
  34.     MenuHandle    aboutMenu;
  35.     long total, contig;
  36.  
  37.     InitGraf ((Ptr) &qd.thePort);
  38.     InitCursor();
  39.     InitFonts();
  40.     InitWindows();
  41.     InitMenus();
  42.     TEInit();
  43.     InitDialogs (0L);
  44.         
  45. //    Make sure System 7 and enough memory are available. If not, exit.
  46.     Assert (System7Available(), NEEDS_SYSTEM_7);
  47.  
  48. //    PPC Toolbox needs System 7    
  49.     InitPPC();
  50.     
  51.     Assert ((long) GetApplLimit() - (long) ApplicZone() >= kMinHeap, INSUFFICIENT_MEMORY);
  52.     PurgeSpace (&total, &contig);
  53.     Assert (total >= kMinSpace, INSUFFICIENT_MEMORY);
  54.                             
  55.     Assert ((menuBar = GetNewMBar (MENU_BAR)) != 0, RESOURCE_MISSING);
  56.     SetMenuBar (menuBar);
  57.     DisposHandle (menuBar);
  58.     AddResMenu (GetMHandle (APPLE_MENU), 'DRVR');    // add DA names to Apple menu
  59.  
  60. //    Add my hierarchical about menus.
  61.     
  62.     {short    i, m;
  63.     Str31    itemText;
  64.     
  65.     for (m = 0; m < 2; m++)
  66.     {
  67.         aboutMenu = NewMenu (m == 0 ? ABOUT_ABALONE_MENU : ABOUT_PROGRAM_MENU, "\pAbout");    // add hierarchical about menu
  68.         for (i = 1; ; i++)
  69.         {
  70.             GetIndString (itemText, m == 0 ? ABOUT_ABALONE_MENU : ABOUT_PROGRAM_MENU, i);
  71.             if (itemText[0] == '\0')
  72.                 break;
  73.     
  74.             AppendMenu (aboutMenu, itemText);
  75.         }
  76.         InsertMenu (aboutMenu, hierMenu);
  77.     }}
  78.     
  79.     DrawMenuBar();
  80.     
  81.     InitAppleEvents();
  82.         
  83.     qd.randSeed = TickCount();
  84.     gProgStartTicks = TickCount();
  85.         
  86.     GetSettings();
  87.     
  88. //    Get & Draw the application window.
  89.     
  90.     gAbaloneWindow = GetNewDialog (rWindow, nil, (WindowPtr) -1);
  91.  
  92.     gBlackAndWhite = ! ColorQDAvailable() || (*(((CWindowPtr) gAbaloneWindow)->portPixMap))->pixelSize == 1;
  93.                 
  94.     SizeWindow (gAbaloneWindow, kHorTotal, kVerTotal, true);
  95.  
  96.     InstallUserItems (gAbaloneWindow);
  97.     if (ColorQDAvailable())    Init3D();
  98.     RestoreColors();
  99. }
  100.  
  101.  
  102.  
  103. void
  104. InstallUserItems (WindowPtr window)
  105. {    
  106.     short    type;
  107.     Rect    box;
  108.     Handle    hndl;
  109.     
  110.     GetDItem (window, 1, & type, & hndl, & box);
  111. #ifdef THINK_C
  112.     SetDItem (window, 1, type, (Handle) (DrawBlackPoints), & box);
  113.     
  114.     GetDItem (window, 2, & type, & hndl, & box);
  115.     SetDItem (window, 2, type, (Handle) (DrawWhitePoints), & box);
  116.     
  117.     GetDItem (window, 3, & type, & hndl, & box);
  118.     SetDItem (window, 3, type, (Handle) (DrawGreenPoints), & box);
  119.     
  120.     GetDItem (window, 4, & type, & hndl, & box);
  121.     SetDItem (window, 4, type, (Handle) (DrawNotationItemProc), & box);
  122. #else
  123.     SetDItem (window, 1, type, (Handle) (NewUserItemProc (DrawBlackPoints)), & box);
  124.     
  125.     GetDItem (window, 2, & type, & hndl, & box);
  126.     SetDItem (window, 2, type, (Handle) (NewUserItemProc (DrawWhitePoints)), & box);
  127.     
  128.     GetDItem (window, 3, & type, & hndl, & box);
  129.     SetDItem (window, 3, type, (Handle) (NewUserItemProc (DrawGreenPoints)), & box);
  130.     
  131.     GetDItem (window, 4, & type, & hndl, & box);
  132.     SetDItem (window, 4, type, (Handle) (NewUserItemProc (DrawNotationItemProc)), & box);
  133. #endif    
  134.     SizeItems (window);
  135. }
  136.  
  137.  
  138.  
  139. //*************************** segment Main ******************************
  140.  
  141.  
  142. #pragma segment Main
  143.  
  144.    
  145. RgnHandle gCursorRgn;
  146.  
  147. void 
  148. main (void)
  149. {    
  150.     #if ! defined(THINK_C) && ! defined(__MWERKS__)
  151.     UnloadSeg ((Ptr) _DataInit);    //    How to do this for Think C?
  152.     #endif
  153.         
  154. //    Try to fairly divide available memory between stack and heap. */
  155.      
  156.     while (StackSpace() > kPrefStack || FreeMem() < kMinHeap)
  157.     {
  158.         SetApplLimit ((void *) ((char *) GetApplLimit() + 1024));
  159.         MaxApplZone();         // expand the heap so code segments load at the top
  160.     }
  161.     
  162.     Initialize();
  163.     #if ! defined(THINK_C)
  164.     UnloadSeg ((Ptr) Initialize);    //    How to do this for Think C?
  165.     #endif
  166.     
  167.     gCursorRgn = NewRgn();    // maintained by AdjustCursor, but must be created here
  168.  
  169.     AdjustMenus();            // before eventloop to make sure disabled menus are dimmed immediately
  170.     
  171.     (void) UserTime();
  172.         
  173.     EventLoop();
  174. }
  175.  
  176.  
  177. //    Get events 'forever' by calling UserTime,
  178. //    alternating with AutoPlay to give time to possible computer players.
  179. //    Both UserTime and AutoPlay test if an End Of Game 'event' occurred,
  180. //    and if so, return the id of the winner.
  181.  
  182. void
  183. EventLoop()
  184. {
  185.     short winner = empty;
  186.     
  187.     while (! gQuitFlag)
  188.     {        
  189.         if (! gQuitFlag && (winner = UserTime()) != empty)
  190.             DoEndOfGame (winner);            
  191.                     
  192.         if (! gQuitFlag && (winner = AutoPlay()) != empty)
  193.             DoEndOfGame (winner);
  194.         
  195.         gInterrupted = false;
  196.     }
  197. }
  198.  
  199.  
  200.  
  201. short
  202. UserTime (void)
  203. {
  204.     EventRecord    event;
  205.     Boolean somethingHappened = false;
  206.  
  207.     while (WaitNextEvent (everyEvent, &event, 1L, gCursorRgn))
  208.     {
  209.         if (event.what != kHighLevelEvent)
  210.             AdjustCursor (& event.where);
  211.             
  212.         DoEvent (&event);
  213.         somethingHappened = true;
  214.     }
  215.     AdjustCursor (& event.where);
  216.     
  217. //    Test for end of game, but only do so if something happened (for efficiency).
  218.     
  219.     return somethingHappened ? EndOfGame() : empty;
  220. }
  221.  
  222.  
  223. //    This is made to be called regularly when computing a move.
  224.  
  225. void
  226. SystemTime (void)
  227. {
  228.     EventRecord    event;
  229.     
  230.     while (WaitNextEvent (everyEvent, &event, 0L, gCursorRgn))
  231.     {
  232.         DoEvent (& event);
  233.         AdjustCursor (& event.where);
  234.     }
  235. }
  236.  
  237.  
  238. //    This is made to be called while waiting for a Apple Event reply.
  239.  
  240. pascal Boolean
  241. IdleTime (EventRecord *event, long sleepTime, RgnHandle mouseRgn)
  242. {
  243.     static Boolean firstTime = true;
  244.     
  245.     if (firstTime)
  246.     {
  247.         firstTime = false;
  248.         sleepTime = 3L;
  249.         mouseRgn = gCursorRgn;
  250.     }
  251.     if (event->what != nullEvent)
  252.     {
  253.         DoEvent (event);
  254.         AdjustCursor (& event->where);
  255.     }
  256.     return false;
  257. }
  258.  
  259.  
  260.  
  261. void
  262. AdjustCursor (Point *mouse)
  263. {
  264.     WindowPtr    window = FrontWindow();    //    We only adjust the cursor when we are in front.
  265.     
  266.     if ((! gInBackground) && (! IsDAWindow (window)) && (IsAppWindow (window)))
  267.     {
  268.         Field f;
  269.         Point loc = *mouse;
  270.         Rect globalFieldRect;
  271.         RgnHandle fieldRgn = NewRgn();
  272.         
  273.         SetPort (window);
  274.         GlobalToLocal (& loc);
  275.         f = LocToField (loc.h, loc.v);
  276.         if (f)
  277.         {
  278.         //    Make a region for the current field, so we get mouseMoved events
  279.         //    when the cursor is moved out of this field
  280.  
  281.             globalFieldRect = FieldToRect (f);
  282.             LocalToGlobal (& TopLeft (globalFieldRect));
  283.             LocalToGlobal (& BotRight (globalFieldRect));
  284.             RectRgn (fieldRgn, & globalFieldRect);
  285.  
  286.             CopyRgn (fieldRgn, gCursorRgn);
  287.         }
  288.         
  289.         if (! PtInRect (loc, & window->portRect))
  290.             CurrentCursor (arrowCursor);
  291.         else if (gSet.PlayerKind[gTheGame.CurrentPlayer] != humanPlayer)
  292.             CurrentCursor (watchCursor);
  293.         else if (EmptyRgn (gCursorRgn))
  294.             CurrentCursor (arrowCursor);
  295.         else if (FieldHasCurrentPlayersBall (f))
  296.             CurrentCursor (blackBallMover + gTheGame.CurrentPlayer - blak);
  297.         else
  298.             CurrentCursor (blackBallSolid + gTheGame.CurrentPlayer - blak);
  299.  
  300.         DisposeRgn (fieldRgn);        
  301.     }
  302. }
  303.  
  304.  
  305.  
  306. void
  307. AdjustMenus (void)
  308. {
  309. //    Enable and disable menus based on the current state.
  310.  
  311.     WindowPtr    window = FrontWindow();
  312.     MenuHandle    menu = GetMHandle (EDIT_MENU);
  313.     short        i;
  314.     
  315.     for (i = EDIT_CUT; i <= EDIT_PASTE; i++)
  316.         EnDisableItem (menu, i, IsDAWindow (window));
  317.     
  318.     EnDisableItem (menu, EDIT_UNDO, BoardsOnStack() > 0);
  319.  
  320.     menu = GetMHandle (SETTINGS_MENU);
  321.     
  322.     EnDisableItem (menu, SETTINGS_GREEN, gTheGame.Players > 2);
  323.     
  324.     for (i = blak; i <= grin; i++)
  325.         SetItemIcon (menu, SETTINGS_BLACK + i - blak, i + (gSet.PlayerKind[i] == macPlayer ? 20 : gSet.PlayerKind[i] != networkPlayer ? 10 : 30));
  326.  
  327.     CheckItem (menu, SETTINGS_2_PLAYERS, gTheGame.Players == 2);
  328.     CheckItem (menu, SETTINGS_3_PLAYERS, gTheGame.Players == 3);
  329.  
  330.     menu = GetMHandle (OPTION_MENU);
  331.     
  332.     EnDisableItem (menu, OPTION_3D_BALLS, ColorQDAvailable());
  333.     CheckItem (menu, OPTION_SOUND, gSet.SoundOn);
  334.     CheckItem (menu, OPTION_3D_BALLS, gSet.Balls3D);
  335.     CheckItem (menu, OPTION_NOTATION, gSet.ShowNotation);
  336.     
  337.     menu = GetMHandle (COLOR_MENU);
  338.     
  339.     EnDisableItem (menu, 0, ! gBlackAndWhite || gSet.Balls3D);
  340.     EnDisableItem (menu, COLOR_GREEN, gTheGame.Players > 2);
  341.  
  342.     menu = GetMHandle (BACKGROUND_MENU);
  343.     
  344.     EnDisableItem (menu, 0, gSet.Balls3D);
  345.     
  346.     DrawMenuBar();
  347. }
  348.  
  349.  
  350.  
  351. Boolean
  352. IsAppWindow (WindowPtr window)
  353. {
  354.     return    (window == nil)
  355.         ?    false
  356.         :        (((WindowPeek) window)->windowKind >= userKind)
  357.             ||    (((WindowPeek) window)->windowKind == dialogKind);
  358. }
  359.  
  360.  
  361.  
  362. Boolean
  363. IsDAWindow (WindowPtr window)
  364. {
  365.     return    (window != nil) && (((WindowPeek) window)->windowKind < 0);
  366. }
  367.  
  368.  
  369.  
  370. void
  371. EnDisableItem (MenuHandle m, short item, Boolean onoff)
  372. {
  373.     if (onoff)
  374.         EnableItem (m, item);
  375.     else
  376.         DisableItem (m, item);
  377. }
  378.  
  379.  
  380. //    To avoid unnecessary overhead with cursor changes,
  381. //    the current cursor is remembered and AdjustCursor only really changes
  382. //    the cursor if there actually is something to change.
  383.  
  384. void
  385. CurrentCursor (short id)
  386. {
  387.     static short current = -1;
  388.     
  389.     if (id == current)
  390.         return;
  391.  
  392.     current = id;
  393.     SetCursor (id == arrowCursor || ! GetCursor (id) ? &qd.arrow : *GetCursor (id));
  394. }
  395.